﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
namespace zmMoniter
{
    class CloseDeck
    {
        private mainForm main = null;
        ArrayList alGraph = new ArrayList();//仓面层面图元数组
        ArrayList alVibGraph = new ArrayList();//振捣图元数组
        ArrayList alTitleGraph = new ArrayList();//仓面层面图元数组
        ArrayList alNonVibrGraph = new ArrayList();//非振捣区域临时点位数组
        ArrayList alLayer = new ArrayList();//本仓面下的铺层ID
        DeckGrider grder = null;
        private string sFlag = "";
        private string sDeckID = "";
        private string sDeckName = "";
        private string sLayerID = "";
        private string sLayerName = "";
        private string sDamBlock = "";

        //覆盖统计
        private double dOverArea = 0;
        private double dNormalArea = 0;
        private double dAbnormalArea = 0;
        private double dInvalidArea = 0;
        private double dTotleArea = 0;
        private int iVibAllowDepth = 55;
        private float fVibAllowAngle = 15;
        private int iVibAllowMinTime = 15;
        private int iVibAllowMaxTime = 17;

        //深度统计
        private float fMaxDepth = -99999;
        private float fMinDepth = 99999;
        private int iDepthSection = 5;
        private int[] Depth = new int[5];

        //时间统计
        private float fMaxTime = -99999;
        private float fMinTime = 99999;
        private int iTimeSection = 5;
        private int[] Time = new int[5];
        //有效统计
        private int[] Qualified = new int[3];
        public  int iQualifiedSection = 3;
        public  CloseDeck(mainForm frm,int DeckID)
        {
            main = frm;
            sDeckID = DeckID.ToString();
            grder = new DeckGrider();
            grder.setReportDrid();
            grder.setGridLength(0.05);
        }
        public  void comput()
        {
            if (sDeckID == "")
            {
                main.pgsPanel.SetBounds(0, 0, 1, 1);
                return;
            }
            System.Threading.Thread th = null;
            th = new Thread(new ThreadStart(this.DoWork));
            
            th.IsBackground = true;
            th.Start();
            
            
        }
        public  void DoWork()
        {
            PublicDataCls db = new PublicDataCls();
            db.OpenConn();
            string sSQL = "SELECT 编号,层编号,层面积,振捣面积,剩余未振捣面积,'' AS 施工状态 FROM 铺层信息表 WHERE 仓面号=" + sDeckID + " Order by 层编号 ASC";
            DataTable dt = db.ReturnDataTable(sSQL);
            db.CloseConn();
            if (dt == null)//modify by lance 2013-1-20
                return;
            
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                DataRow dataRow = dt.Rows[i];
                sLayerID = dataRow["层编号"].ToString().Trim();
                alLayer.Add(sLayerID);
                clearGraph();
                DoQualifiedWork();
            }
            main.pgsPanel.Description = "将关仓状态写入数据库...";
            //写入服务器统计报表（该功能暂未实现）

            db.OpenConn();
            DateTime now = System.DateTime.Now;
            sSQL = "UPDATE 仓面信息 SET 开仓状态=0,结束时间=to_date('" + now.ToString("yyyy/MM/dd hh:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')" + " WHERE 编号=" + sDeckID;
            
            int iResult = db.ExecuteSQL(sSQL);
            if (iResult > 0)
            {
                main.pgsPanel.Description = "通知监控服务端...";
                main.seedMessage("00;" + sDeckID);
                main.setDeckState(int.Parse(sDeckID), 0);

                main.pgsPanel.Description = "通知监控服务端成功！";
                // MessageBox.Show("关仓成功！", "关仓提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                main.pgsPanel.Description = "通知监控服务端失败！";
                //MessageBox.Show("关仓失败！", "关仓提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            db.CloseConn();
            main.pgsPanel.Description = "更新图形！";
            main.upDateGraph();
            main.pgsPanel.SetBounds(0, 0, 1, 1);

        }
        private void DoQualifiedWork()
        {
            main.pgsPanel.Description = "统计第" + sLayerID + "铺层振捣结果";
            PublicDataCls db = new PublicDataCls();
            db.OpenConn();
            string sSQL = "select 铺层信息表.*,仓面信息.仓面名称,仓面信息.坝段,仓面信息.上下游块,仓面信息.最低高程,仓面信息.最高高程," +
            "仓面信息.振捣边界点,仓面信息.铺层厚度,仓面信息.开仓状态,仓面信息.仓面控制点,仓面信息.开仓时间,仓面信息.结束时间 " +
            "from 铺层信息表,仓面信息 WHERE 铺层信息表.仓面号=仓面信息.编号 AND 铺层信息表.层编号=" + sLayerID + " AND 铺层信息表.仓面号=" + sDeckID;
            DataTable dt = db.ReturnDataTable(sSQL);
            db.CloseConn();
            if (dt == null)//modify by lance 2013-1-20
                return;
            int iCount = dt.Rows.Count;
            if (iCount == 0)
                return;
            DataRow dataRow = dt.Rows[0];
            sDeckName = dataRow["仓面名称"].ToString().Trim();
            sLayerName = dataRow["层编号"].ToString().Trim();
            sDamBlock = sDeckName.Substring(0, sDeckName.LastIndexOf('-'));
            //float fArea = float.Parse(dataRow["剩余未振捣面积"].ToString().Trim());
            float fhMin = float.Parse(dataRow["最低高程"].ToString().Trim());
            float fhMax = float.Parse(dataRow["最高高程"].ToString().Trim());
            string strDeckFence = dataRow["仓面控制点"].ToString().Trim();
            string strVbtFence = dataRow["振捣边界点"].ToString().Trim();
            string strLayerFence = dataRow["层边界控制点"].ToString().Trim();
            string strStartTime = dataRow["开仓时间"].ToString().Trim();
            string strEndTime = dataRow["结束时间"].ToString().Trim();

            

            string[] sPoints = strDeckFence.Split(';');
            Graph gObj = new Graph(1, 3);
            gObj.setPen(new Pen(Color.Black, 3));
            for (int i = 0; i < sPoints.Length; i++)
            {
                string[] sXY = sPoints[i].Split(',');
                if (sXY.Length == 2)
                {
                    gObj.addPoint(new Point(double.Parse(sXY[0]), double.Parse(sXY[1])));
                    addGraph(gObj);
                }
            }
            getVibrators();
            sPoints = strVbtFence.Split(';');
            gObj = new Graph(1, 3);
            gObj.setPen(new Pen(Color.Blue, 1));
            for (int i = 0; i < sPoints.Length; i++)
            {
                string[] sXY = sPoints[i].Split(',');
                if (sXY.Length == 2)
                {
                    gObj.addPoint(new Point(double.Parse(sXY[0]), double.Parse(sXY[1])));
                    gObj.setFlag("振捣边界");
                    addGraph(gObj);
                }
            }

            sPoints = strLayerFence.Split(';');
            gObj = new Graph(1, 3);
            gObj.setPen(new Pen(Color.Orange, 1));
            for (int i = 0; i < sPoints.Length; i++)
            {
                string[] sXY = sPoints[i].Split(',');
                if (sXY.Length == 2)
                {
                    gObj.addPoint(new Point(double.Parse(sXY[0]), double.Parse(sXY[1])));
                    addGraph(gObj);
                }
            }

            upDateNonVibr();
            setGrid(strVbtFence);
            writeResult();
        }
        private void writeResult()
        {
            PublicDataCls db = new PublicDataCls();
            db.OpenConn();
            int iTotleGrd = (Qualified[0] + Qualified[1] + Qualified[2]);
            double dTotleArea = iTotleGrd * grder.dGridLenth * grder.dGridLenth;//总面积
            double dTotleArea1 = Qualified[0] * grder.dGridLenth * grder.dGridLenth;//未振捣面积
            double dTotleArea2 = Qualified[1] * grder.dGridLenth * grder.dGridLenth;//合格面积
            double dTotleArea3 = Qualified[2] * grder.dGridLenth * grder.dGridLenth;//不合格面积
            double dTotleArea4 = (Qualified[1] + Qualified[2]) * grder.dGridLenth * grder.dGridLenth;//振捣面积
            string sSQL = "UPDATE 铺层信息表 SET 振捣面积=" + dTotleArea4.ToString() + 
                ",合格面积=" + dTotleArea2.ToString() + ",不合格面积=" + dTotleArea3.ToString() + 
                ",剩余未振捣面积=" + dTotleArea1.ToString() + " WHERE 层编号=" + sLayerID + " AND 仓面号=" + sDeckID;
            db.ExecuteSQL(sSQL);
            db.CloseConn();
        }
        private void computQualified()
        {
            for (int m = 0; m < grder.grdBlock.Count; m++)
            {
                Grid grd = (Grid)grder.grdBlock[m];
                if (grd.getOverLay() == -9999)//外围区域
                    continue;
                for (int n = 0; n < alNonVibrGraph.Count; n++)
                {
                    NonVibrators nonVibr = (NonVibrators)alNonVibrGraph[n];
                    if (nonVibr.IsIn(grd.fLX, grd.fTY, grder.dGridLenth))//非振捣区域
                        grd.setOverLay(-1);
                }
                for (int p = 0; p < alVibGraph.Count; p++)
                {
                    VibGraph gVibr = (VibGraph)alVibGraph[p];
                    if (gVibr.IsIn(grd.fLX, grd.fTY, grder.dGridLenth))//振捣覆盖
                    {
                        grd.setTime(gVibr.iVibTime);
                        grd.setDepth(gVibr.fVibDepth);
                        grd.setOverLay(1);
                    }
                }
            }
            
            for (int m = 0; m < grder.grdBlock.Count; m++)
            {
                Grid grd = (Grid)grder.grdBlock[m];
                if (grd.getOverLay() == -9999)//外围区域
                {
                    continue;
                }
                else if (grd.getOverLay() == 0)//未振捣
                {
                    Qualified[0]++;
                    grd.setQualified(0);
                    continue;
                }
                else if (grd.getOverLay() == -1)//内部非振捣区域
                {
                    grd.setQualified(-1);
                    continue;
                }
                if ((grd.getTime() < iVibAllowMinTime || grd.getTime() > iVibAllowMaxTime) && grd.getOverLay()>0)
                {
                    Qualified[2]++;
                    grd.setQualified(2);
                    continue;
                }
                else if (grd.getDepth() < iVibAllowDepth && grd.getOverLay() > 0)
                {
                    Qualified[2]++;
                    grd.setQualified(2);
                    continue;
                }
                else if (grd.getOverLay() > 2)
                {
                    Qualified[2]++;
                    grd.setQualified(2);
                    continue;
                }
                Qualified[1]++;
                grd.setQualified(1);
            }
        }
        public  void setGrid(string sPoints)
        {
            string[] strPoints = sPoints.Split(';');
            for (int i = 0; i < strPoints.Length; i++)
            {
                string[] strXY = strPoints[i].Split(',');
                if (strXY.Length < 2)
                    continue;
                Point pt = new Point(double.Parse(strXY[0]), double.Parse(strXY[1]));
                grder.addPoint(pt);
            }
            grder.setGridPoint();
           
            computQualified();
           
        }
        public  void getVibrators()
        {
            alVibGraph.Clear();
            fMaxDepth = -99999;
            fMinDepth = 99999;
            PublicDataCls db = new PublicDataCls();
            db.OpenConn();
            string sOrderDepthSQL = " Order by 振捣监控点位数据表.振捣深度 DESC";
            string sOrderTimeSQL = " Order by 振捣监控点位数据表.振捣时长 DESC";
            string sSQL = "select 振捣监控点位数据表.*," +
            "振捣设备基本信息表.编号 as 设备编号,振捣设备基本信息表.型号,振捣设备基本信息表.振动棒数量,振捣设备基本信息表.履带长," +
            "振捣设备基本信息表.履带宽,振捣设备基本信息表.棒头头长," +
            "振捣设备基本信息表.棒头总长,振捣设备基本信息表.振动影响区域,振捣设备基本信息表.使用设备状态," +
            "振捣参数控制标准.振捣深度 AS 容许振捣深度,振捣参数控制标准.容许插入角度偏差,振捣参数控制标准.振捣时间上限,振捣参数控制标准.振捣时间下限 " +
            "FROM 振捣监控点位数据表 LEFT OUTER JOIN 振捣设备基本信息表 ON 振捣监控点位数据表.设备编号 = 振捣设备基本信息表.编号 " +
            "LEFT OUTER JOIN 振捣参数控制标准 ON 振捣监控点位数据表.仓面号= 振捣参数控制标准.仓面号 " +
            "WHERE 振捣监控点位数据表.铺层编号=" + sLayerName +
            " AND 振捣监控点位数据表.仓面号=" + sDeckID;
            if (sFlag == "Depth")
                sSQL += sOrderDepthSQL;
            else if (sFlag == "Time")
                sSQL += sOrderTimeSQL;
            DataTable dt = db.ReturnDataTable(sSQL);
            db.CloseConn();
            if (dt == null)//modify by lance 2013-1-20
                return;
            int iCount = dt.Rows.Count;
            if (iCount == 0)
                return;
            for (int i = 0; i < iCount; i++)
            {
                DataRow dataRow = dt.Rows[i];

                float fX = float.Parse(dataRow["X"].ToString().Trim());
                float fY = float.Parse(dataRow["Y"].ToString().Trim());
                string strVibID = dataRow["设备编号"].ToString().Trim();
                string strVibCN = dataRow["型号"].ToString().Trim();
                string strVibFence = dataRow["振动影响区域"].ToString().Trim();
                float fVibAngle = float.Parse(dataRow["振捣方位角"].ToString().Trim());
                float fVibDepth = float.Parse(dataRow["振捣深度"].ToString().Trim());
                int iVibTime = int.Parse(dataRow["振捣时长"].ToString().Trim());
                iVibAllowDepth = int.Parse(dataRow["容许振捣深度"].ToString().Trim());
                fVibAllowAngle = float.Parse(dataRow["容许插入角度偏差"].ToString().Trim());
                iVibAllowMinTime = int.Parse(dataRow["振捣时间上限"].ToString().Trim());
                iVibAllowMaxTime = int.Parse(dataRow["振捣时间下限"].ToString().Trim());

                fMaxDepth = fVibDepth > fMaxDepth ? fVibDepth : fMaxDepth;
                fMinDepth = fVibDepth > fMinDepth ? fMinDepth : fVibDepth;

                fMaxTime = iVibTime > fMaxTime ? iVibTime : fMaxTime;
                fMinTime = iVibTime > fMinTime ? fMinTime : iVibTime;

                string[] sPoints = strVibFence.Split(';');
                VibGraph gObj = new VibGraph(1, 31);
                gObj.setPen(new Pen(Color.FromArgb(160, ColorTranslator.FromWin32(Properties.Settings.Default.ep_color8)), 1));
                gObj.setParam(fVibDepth, fVibAngle, iVibTime);
                for (int j = 0; j < sPoints.Length; j++)
                {
                    string[] sXY = sPoints[j].Split(',');
                    if (sXY.Length == 2)
                    {
                        gObj.addPoint(angleTranslate(fX, fY, double.Parse(sXY[0]), double.Parse(sXY[1]), fVibAngle * Math.PI / 180));
                    }
                }
                gObj.setRegion();
                alVibGraph.Add(gObj);
            }
        }
        private Point angleTranslate(double dfx, double dfy, double dx, double dy, double fAngle)
        {
            double sin = Math.Sin(fAngle);
            double cos = Math.Cos(fAngle);

            double x = dx * cos - dy * sin;
            double y = dx * sin + dy * cos;
            return new Point(dfx + x, dfy + y);
        }
        public  void upDateNonVibr()
        {
            alNonVibrGraph.Clear();
            PublicDataCls db = new PublicDataCls();
            db.OpenConn();
            string sSQL = "select 非振捣区域.* from 非振捣区域 WHERE 仓面号=" + sDeckID + " AND 层号=" + sLayerID;
            DataTable dt = db.ReturnDataTable(sSQL);
            db.CloseConn();
            if (dt == null)//modify by lance 2013-1-20
                return;
            int iCount = dt.Rows.Count;
            if (iCount == 0)
                return;
            for (int i = 0; i < iCount; i++)
            {
                DataRow dataRow = dt.Rows[i];


                double dArea = -1;
                string sArea = dataRow["面积"].ToString().Trim();
                if (sArea != "")
                    dArea = float.Parse(sArea);

                int iColor = int.Parse(dataRow["显示颜色"].ToString().Trim());
                string strVbtFence = dataRow["非振捣点位"].ToString().Trim();
                double dCenterX = -1;
                double dCenterY = -1;

                NonVibrators nonVibr = new NonVibrators();
                getCenterXY(strVbtFence, ref nonVibr);
                nonVibr.sName = dataRow["名称"].ToString().Trim();
                nonVibr.sID = dataRow["编号"].ToString().Trim();
                nonVibr.sDisc = dataRow["说明"].ToString().Trim();
                nonVibr.iColor = int.Parse(dataRow["显示颜色"].ToString().Trim());
                nonVibr.dArea = dArea;
                nonVibr.setRegion();
                alNonVibrGraph.Add(nonVibr);
            }
        }
        private void getCenterXY(string strVbtFence, ref NonVibrators nonVibr)
        {
            string[] strXYs = strVbtFence.Split(';');
            if (strXYs.Length == 0)
                return;
            double dCenterX = 0;
            double dCenterY = 0;
            for (int i = 0; i < strXYs.Length; i++)
            {
                string[] sXY = strXYs[i].Split(',');
                if (sXY.Length != 2)
                    continue;
                double dx = double.Parse(sXY[0]);
                double dy = double.Parse(sXY[1]);
                Point pt = new Point(dx, dy);

                nonVibr.addPoint(pt);
                dCenterX += dx;
                dCenterY += dy;
            }
            nonVibr.dCenterX = dCenterX * 1.0 / strXYs.Length;
            nonVibr.dCenterY = dCenterY * 1.0 / strXYs.Length;
        }
        private void addGraph(Graph gObj)
        {
            alGraph.Add(gObj);

        }
        private void clearGraph()
        {
            alGraph.Clear();
            alVibGraph.Clear();
            alTitleGraph.Clear();
            alNonVibrGraph.Clear();
            if (grder != null)
                grder.clear();
            dNormalArea = 0;
            dAbnormalArea = 0;
            dInvalidArea = 0;
            dTotleArea = 0;
            dOverArea = 0;

            iVibAllowDepth = 55;
            fVibAllowAngle = 15;
            iVibAllowMinTime = 15;
            iVibAllowMaxTime = 17;

            //深度统计
            fMaxDepth = -99999;
            fMinDepth = 99999;

            Depth[0] = Depth[1] = Depth[2] = Depth[3] = Depth[4] = 0;

            //时间统计
            fMaxTime = -99999;
            fMinTime = 99999;
            Time[0] = Time[1] = Time[2] = Time[3] = Time[4] = 0;


            //有效统计
            Qualified[0] = Qualified[1] = Qualified[2] = 0;
        }
    }
}
